package cn.t.service.user;


import cn.t.constants.CommonConstants;
import cn.t.constants.Constants;
import cn.t.core.exception.BizException;
import cn.t.core.mode.YesNoEnum;
import cn.t.core.service.ServiceImpl;
import cn.t.core.enums.base.BaseStatusEnum;
import cn.t.core.enums.base.CommonError;
import cn.t.model.user.CustomerFirmDO;
import cn.t.repository.user.CustomerFirmRepository;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 单位信息表领域服务
 *
 * @author l
 */
@Slf4j
@Service
@AllArgsConstructor
public class CustomerFirmService extends ServiceImpl<CustomerFirmDO, CustomerFirmRepository> {


    public void isDuplicatedFirm(Long firmId, String firmCode) {
        CustomerFirmDO customerFirmDO = queryFirmByCode(firmCode);
        if (customerFirmDO == null) {
            return;
        }

        if (firmId == null) {
            String errorMessage = String.format("客户号重复 firmCode=%s", firmCode);
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        if (!firmId.equals(customerFirmDO.getCustomerId())) {
            String errorMessage = String.format("客户号重复 firmCode=%s", firmCode);
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }
    }

    public CustomerFirmDO queryFirmByCode(String firmCode) {
        CustomerFirmDO template = new CustomerFirmDO();
        template.setFirmCode(firmCode);
        template.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));

        List<CustomerFirmDO> customerFirms = repository.findByModel(template, 0, 1, "", "");
        return CollectionUtils.isEmpty(customerFirms) ? null : customerFirms.get(0);
    }


    public CustomerFirmDO isExistedFirm(Long firmId) {
        CustomerFirmDO customerFirm = findById(firmId);
        if (customerFirm == null || customerFirm.getId() == null || !customerFirm.getId().equals(firmId)) {
            String errorMessage = String.format("指定的企业不存在 firmId=%d", firmId);
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        } else if (!String.valueOf(BaseStatusEnum.AVAILABLE.getCode()).equals(customerFirm.getStatus())
                || !YesNoEnum.FALSE.equals(customerFirm.getIsDeleted())) {
            String errorMessage = String.format("指定的企业不可用 firmId=%d", customerFirm.getId());
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        return customerFirm;
    }

    public Map<Long, String> getFirmIdNameMap(List<Long> firmIds) {
        CustomerFirmDO firmQueryParams = new CustomerFirmDO();
        firmQueryParams.setFirmIds(firmIds);
        List<CustomerFirmDO> firms = this.findByModel(firmQueryParams, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);

        Map<Long, String> firmIdNameMap = new HashMap<>();
        firms.forEach(firm -> firmIdNameMap.put(firm.getId(), firm.getFirmName()));
        return firmIdNameMap;
    }
    public Map<Long, CustomerFirmDO> getFirmInfoMap(List<Long> firmIds) {
        CustomerFirmDO firmQueryParams = new CustomerFirmDO();
        firmQueryParams.setFirmIds(firmIds);
        List<CustomerFirmDO> firms = this.findByModel(firmQueryParams, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);

        Map<Long, CustomerFirmDO> firmIdNameMap = new HashMap<>();
        firms.forEach(firm -> firmIdNameMap.put(firm.getId(), firm));
        return firmIdNameMap;
    }
    public List<CustomerFirmDO> getAllFirm() {
        return this.findByModel(new CustomerFirmDO(), CommonConstants.ZERO, Integer.MAX_VALUE, null, null);
    }

    public CustomerFirmDO getCustomerUser() {

        CustomerFirmDO template = new CustomerFirmDO();
        template.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));
        template.setIsDeleted(YesNoEnum.FALSE);

        Optional<CustomerFirmDO> optional = repository.findByModel(template, 0, 100, "id", "asc").stream().findFirst();

        return optional.orElse(null);

    }

    public CustomerFirmDO findByCode(String firmCode) {
        String redisKey = Constants.REDIS_KEY__CUSTOMER_FIRM__CODE + firmCode;

        if (redissonClient.getBucket(redisKey).isExists()) {
            return (CustomerFirmDO) redissonClient.getBucket(redisKey).get();
        }

        CustomerFirmDO template = new CustomerFirmDO();
        template.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));
        template.setIsDeleted(YesNoEnum.FALSE);
        template.setFirmCode(firmCode);

        Optional<CustomerFirmDO> optional = repository.findByModel(template, 0, 1, "id", "asc").stream().findFirst();

        optional.ifPresent(firmDO -> redissonClient.getBucket(redisKey).set(firmDO, 5, TimeUnit.MINUTES));

        return optional.orElse(null);
    }

    @Autowired
    private RedissonClient redissonClient;
}
